/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package apteka;

import apteka.tables.Address;
import apteka.tables.Basket;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.springframework.stereotype.Component;
import apteka.tables.User;
import java.math.BigInteger;
import java.security.*;
import java.util.ArrayList;
import java.util.Random;
import java.util.Set;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.GrantedAuthorityImpl;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.transaction.annotation.Transactional;

/**
 *
 * @author Marek
 */

@Component
public class UserManager implements UserDetailsService {

    Session session=null;
    private String adminName;
    private String adminPassword;

    public String getAdminName() {
        return adminName;
    }

    public void setAdminName(String adminName) {
        this.adminName = adminName;
    }

    public String getAdminPassword() {
        return adminPassword;
    }

    public void setAdminPassword(String adminPassword) {
        this.adminPassword = adminPassword;
    }



    public UserManager() {
        session=HibernateUtil.getSession();
    }

    public boolean checkUsername(String username) {
        boolean result = false;
        try {
            Transaction trans = session.beginTransaction();
            Query q = session.createQuery("FROM User as user WHERE user.username='"+username+"'");
            if (q.uniqueResult()!=null) result=true;

        } catch (Exception e) {
            System.out.println(e.toString());
        }
        return result;
    }

    public String generateHash(String pass) {
        try {
            MessageDigest md5 = MessageDigest.getInstance("MD5");
            md5.update(pass.getBytes());
            BigInteger hash = new BigInteger(1, md5.digest());
            return hash.toString(16);
        } catch (Exception e) {
            System.out.println(e.toString());
        }
        return null;
    }

    public String generateToken() {
        String token="";
        Random rand= new Random();
        for (int a=0;a<32;a++) {
            if (rand.nextBoolean()==true)
                token+=(char)(65+rand.nextInt(24));
            else
                token+=(char)(97+rand.nextInt(24));
        }
        return token;
    }

    public void registerUser(User user) {
        Transaction trans = null;
        try {
            trans = session.beginTransaction();
            trans.begin();
            user.setPassword(generateHash(user.getPassword()));
            session.save(user.getBasket());
            session.evict(Basket.class);
            session.save(user.getAddress());
            session.save(user);
            user.getAddress().setUser(user.getIduser());
            session.update(user.getAddress());
            trans.commit();
        } catch (Exception e) {
            System.out.println(e.toString());
            trans.rollback();
        }
    }

    public String activateUser(String token) {
        String result="";
        try {
            Transaction trans = session.beginTransaction();
            Query q = session.createQuery("FROM User as user WHERE user.active=FALSE AND user.activatecode='"+token+"' ORDER BY user.registerdate");
            if (q.uniqueResult()!=null) {
                User usr = (User)q.uniqueResult();
                usr.setActivatecode("");
                usr.setActive(true);
                result=usr.getUsername();
                session.update(usr);
                session.flush();
                session.evict(apteka.tables.User.class);
                trans.commit();
            }
        } catch (Exception e) {
            System.out.println(e.toString());
        }
        return result;
    }

   public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException,org.springframework.dao.DataAccessException {
       
       

       User usr = null;
       if (!username.equals(adminName)) {
        try {
            Transaction trans = session.beginTransaction();
            Query q = session.createQuery("FROM User as user WHERE user.username='"+username+"'");
            if (q.uniqueResult()!=null) {
                usr = (User)q.uniqueResult();
                usr.setAdmin(false);
            } else {
                throw new UsernameNotFoundException("");
            }

        } catch (Exception e) {
            System.out.println(e.toString());
        }
       } else {
           usr = new User(adminName,adminPassword,true,true);
       }
        return (UserDetails)usr;

    }

}
